# triangulatedpolygon.py
#
# A class representing a triangulated polygon, with functions
# for dealing with the xml scene

import xmlscene
from xmlscene_functions import *
from transformations import identityTransformationMatrix
import utah_teapot

import numpy
import unittest

class TriangulatedPolygon():
    def setTriangleProperties(self, triangle, triangle_parent):
        if isRGBStringBlack(triangle.get_emission()):
            triangle.set_emission(triangle_parent.get_emission())
        if isRGBStringBlack(triangle.get_reflectivity()):
            triangle.set_reflectivity(triangle_parent.get_reflectivity())
        if isRGBStringBlack(triangle.get_radiosity()):
            triangle.set_radiosity(triangle_parent.get_radiosity())

    def addTriangle(self, triangle, triangle_parent):
        self.setTriangleProperties(triangle, triangle_parent)

        # apply the transformation matrix to each vertex of the triangle
        vertices = []
        for i in range(len(triangle.get_vertex())):
            vertex = triangle.get_vertex()[i]
            # NOTE: do not modify vertex directly, but create a new vertex
            #       so that vertices created from references do not update
            #       with the transformed vertex
            row_vector = numpy.matrix([[vertex.x], [vertex.y], [vertex.z], [1.0]])
            transformed_vector = self.transformation_matrix*row_vector
            h_inv = 1.0/transformed_vector.item(3, 0)
            tv_x = transformed_vector.item(0, 0)*h_inv
            tv_y = transformed_vector.item(1, 0)*h_inv
            tv_z = transformed_vector.item(2, 0)*h_inv
            vertices.append(xmlscene.vertex(x = tv_x, y = tv_y, z = tv_z))
        triangle.set_vertex(vertices)
        self.triangles.append(triangle)

    def triangulateRectangle(self, rectangle, rectangle_parent):
        # rectangle = [4 xmlscene.vertex objects]
        # the vertices must be given in either ccw or cw order,
        # and we split the rectangle's diagonal in the given order
        self.addTriangle(xmlscene.triangle(vertex=[rectangle[0], rectangle[1], rectangle[2]]), rectangle_parent)
        self.addTriangle(xmlscene.triangle(vertex=[rectangle[0], rectangle[2], rectangle[3]]), rectangle_parent)

    def triangulateBase(self, base, base_parent):
        # base has the same specification as rectangle in triangulateRectangle
        self.addTriangle(xmlscene.triangle(vertex=[base[1],
                                                   base[0],
                                                   xmlscene.vertex(x = 0.0, z = 0.0, y = base[1].y)]),
                         base_parent)
        self.addTriangle(xmlscene.triangle(vertex=[base[3],
                                                   base[2],
                                                   xmlscene.vertex(x = 0.0, z = 0.0, y = base[3].y)]),
                         base_parent)

    def triangulateTriangleSet(self, triangleset):
        # all the triangles must come before any trianglenexts
        triangles = triangleset.get_triangle()
        for triangle in triangles:
            triangle_vertices = triangle.get_vertex()
            vertices = []
            for i in xrange(3):
                vertices.append(xmlscene.vertex(x = triangle_vertices[i].x, 
                                                y = triangle_vertices[i].y, 
                                                z = triangle_vertices[i].z))
            self.addTriangle(xmlscene.triangle(vertex=vertices), triangleset)

        # trianglenext implies its vertices from the previous triangle or trianglenext
        v0 = triangles[len(triangles)-1].vertex[0]
        v1 = triangles[len(triangles)-1].vertex[1]
        v2 = triangles[len(triangles)-1].vertex[2]
        next_triangles = triangleset.trianglenext
        for i in xrange(len(next_triangles)):
            if i%2 == 0:
                v0 = v1
                v1 = next_triangles[i].get_vertex()
            else:
                v0 = v2
                v2 = next_triangles[i].get_vertex()
            vertices = [xmlscene.vertex(x = v0.x, y = v0.y, z = v0.z),
                        xmlscene.vertex(x = v1.x, y = v1.y, z = v1.z),
                        xmlscene.vertex(x = v2.x, y = v2.y, z = v2.z)]
            self.addTriangle(xmlscene.triangle(vertex=vertices), triangleset)

    def triangulateCuboid(self, cuboid):
        # Each rectangle of the cuboid is divided into 2 triangles
        # TODO: original rrv's cuboids are 1x1x1 with center at 0,0,0 => extend?

        # left
        self.triangulateRectangle([xmlscene.vertex(x = -0.5, y = -0.5, z = -0.5),
                                  xmlscene.vertex(x = -0.5, y = -0.5, z = +0.5),
                                  xmlscene.vertex(x = -0.5, y = +0.5, z = +0.5),
                                  xmlscene.vertex(x = -0.5, y = +0.5, z = -0.5)],
                                 cuboid)
        # right
        self.triangulateRectangle([xmlscene.vertex(x = +0.5, y = -0.5, z = -0.5),
                                   xmlscene.vertex(x = +0.5, y = +0.5, z = -0.5),
                                   xmlscene.vertex(x = +0.5, y = +0.5, z = +0.5),
                                   xmlscene.vertex(x = +0.5, y = -0.5, z = +0.5)],
                                  cuboid)
        # down
        self.triangulateRectangle([xmlscene.vertex(x = -0.5, y = -0.5, z = -0.5),
                                   xmlscene.vertex(x = +0.5, y = -0.5, z = -0.5),
                                   xmlscene.vertex(x = +0.5, y = -0.5, z = +0.5),
                                   xmlscene.vertex(x = -0.5, y = -0.5, z = +0.5)],
                                  cuboid)
        # up
        self.triangulateRectangle([xmlscene.vertex(x = -0.5, y = +0.5, z = -0.5),
                                   xmlscene.vertex(x = -0.5, y = +0.5, z = +0.5),
                                   xmlscene.vertex(x = +0.5, y = +0.5, z = +0.5),
                                   xmlscene.vertex(x = +0.5, y = +0.5, z = -0.5)],
                                  cuboid)
        # rear
        self.triangulateRectangle([xmlscene.vertex(x = -0.5, y = -0.5, z = -0.5),
                                   xmlscene.vertex(x = -0.5, y = +0.5, z = -0.5),
                                   xmlscene.vertex(x = +0.5, y = +0.5, z = -0.5),
                                   xmlscene.vertex(x = +0.5, y = -0.5, z = -0.5)],
                                  cuboid)
        # front
        self.triangulateRectangle([xmlscene.vertex(x = -0.5, y = -0.5, z = +0.5),
                                   xmlscene.vertex(x = +0.5, y = -0.5, z = +0.5),
                                   xmlscene.vertex(x = +0.5, y = +0.5, z = +0.5),
                                   xmlscene.vertex(x = -0.5, y = +0.5, z = +0.5)],
                                  cuboid)

    def triangulateBarrel(self, barrel, slices=20, radius=0.5): # NOTE: a "barrel" in the rrv code is a cylinder => TODO: correct this terminology?
        # TODO: original rrv's barrels are cylinders with radius 0.5, height 1.0, and center 0,0,0
        # => extend?
        v = zeroPolygon(4)
        for i in xrange(slices+1):
            v[3] = copyVertex(v[2])
            v[0] = copyVertex(v[1])
            
            angle = 2.0*(math.pi/slices)*float(i)
            x = radius*math.cos(angle)
            z = radius*math.sin(angle)
            
            v[2].x = x
            v[2].y = -0.5
            v[2].z = z
            
            v[1].x = x
            v[1].y = +0.5
            v[1].z = z
            
            if i != 0:
                self.triangulateRectangle([v[0], v[1], v[2], v[3]], barrel)
                self.triangulateBase([v[0], v[1], v[2], v[3]], barrel)

    def triangulateGlobe(self, globe, slices=20, radius=0.5): # NOTE: a "globe" in the rrv code is a sphere
        # TODO: original rrv's globes are spheres with radius 0.5 and center 0,0,0
        # => extend?
        previous_vertices = []
        this_vertex = zeroVertex()
        current_vertex = zeroVertex()
        quad = zeroPolygon(4)
        for outer in range(slices/2 + 1):
            angle = 2*(math.pi/slices)*outer
            x0 = radius*math.cos(angle)
            z0 = radius*math.sin(angle)
            for inner in range(slices + 3):
                angle = 2*(math.pi/slices)*inner
                x = z0*math.cos(angle)
                z = z0*math.sin(angle)

                current_vertex.x = x
                current_vertex.y = x0
                current_vertex.z = z

                if outer == 0:
                    prev_v = zeroVertex()
                    prev_v.y = radius
                    previous_vertices.append(prev_v)
                else:
                    if inner == 0:
                        this_vertex = current_vertex
                    else:
                        quad[0] = current_vertex
                        quad[1] = this_vertex
                        quad[2] = previous_vertices[inner - 1]
                        quad[3] = previous_vertices[inner]

                        if outer == slices/2:
                            quad[0].x = 0.0
                            quad[0].z = 0.0
                            quad[1].x = 0.0
                            quad[1].z = 0.0

                        if inner != (slices + 2) and inner != 1:
                            self.triangulateRectangle(quad, globe)

                        previous_vertices[inner - 1] = this_vertex
                        this_vertex = current_vertex

        return self

    def triangulateTeapot(self, teapot):
        # A Utah Teapot. Bottom of this teapot
        # is at 0,0,0.
        for i in xrange(len(utah_teapot.teapot_mesh_indices)):
            vertices = []
            for j in xrange(3):
                vertex = xmlscene.vertex(x=utah_teapot.teapot_mesh_vertices[utah_teapot.teapot_mesh_indices[i][2-j]][0],
                                         y=utah_teapot.teapot_mesh_vertices[utah_teapot.teapot_mesh_indices[i][2-j]][2],
                                         z=utah_teapot.teapot_mesh_vertices[utah_teapot.teapot_mesh_indices[i][2-j]][1])
                vertices.append(vertex)
            self.addTriangle(xmlscene.triangle(vertex=vertices), teapot)

    def triangulate(self, object):
        triangulationFunction = self.object_dictionary[object.__class__]
        triangulationFunction(object) # TODO: additional arguments

    def divideTriangles(self, size):
        new_triangles = []
        stack = []
        for triangle in self.triangles:
            stack.append(triangle)

        while len(stack) != 0:
            top = stack[0]
            del(stack[0])
            if triangleArea(top) <= size:
                new_triangles.append(top)
            else:
                divided_triangles = divideTriangle(top)
                for i in xrange(len(divided_triangles)):
                    self.setTriangleProperties(divided_triangles[i], top)
                    stack.insert(0, divided_triangles[i])

        self.triangles = new_triangles

    def __init__(self, triangles=None, transformation_matrix=identityTransformationMatrix(), name=None, object=None):
        if triangles is None:
            self.triangles = []
        else:
            self.triangles = triangles
        self.transformation_matrix = transformation_matrix
        self.name = name
        self.object_dictionary = {xmlscene.triangleset : self.triangulateTriangleSet,
                                  xmlscene.cuboid : self.triangulateCuboid,
                                  xmlscene.barrel : self.triangulateBarrel,
                                  xmlscene.globe : self.triangulateGlobe,
                                  xmlscene.teapot : self.triangulateTeapot}
        if object is not None:
            self.triangulate(object)

if __name__ == '__main__':
    from xmlscenereader import readScene
    from xmlscenewriter import writeScene

    class TestRadiosityRelaxation(unittest.TestCase):

        def setUp(self):
            self.infile = "./xml_test_files/test_scene.xml"
            self.inscene = readScene(self.infile)
            self.transformations = applyMacros(self.inscene)

            self.triangleset = self.inscene.get_head().get_objectdef()[0].get_triangleset()[0]
            self.triangleset_objectdef = self.inscene.get_head().get_objectdef()[0]

            self.cuboid = self.inscene.get_head().get_objectdef()[3].get_cuboid()[0]
            self.cuboid_objectdef = self.inscene.get_head().get_objectdef()[3]

            self.barrel_objectdef = self.inscene.get_head().get_objectdef()[2]
            self.barrel = self.barrel_objectdef.get_barrel()[0]

            self.teapot_objectdef = self.inscene.get_head().get_objectdef()[4]
            self.teapot = self.teapot_objectdef.get_teapot()[0]

        def test_triangleset_triangulation_no_transformation(self):
            triangleset_triangulated = TriangulatedPolygon(object=self.triangleset, name=self.triangleset_objectdef.get_name())
            self.assert_(len(triangleset_triangulated.triangles) == 2)
            self.assert_(triangleset_triangulated.triangles[0].vertex[0].x == 10.0 and
                         triangleset_triangulated.triangles[0].vertex[0].y == -10.0 and
                         triangleset_triangulated.triangles[0].vertex[0].z == 0.0 and
                         triangleset_triangulated.triangles[0].vertex[1].x == 10.0 and
                         triangleset_triangulated.triangles[0].vertex[1].y == 10.0 and
                         triangleset_triangulated.triangles[0].vertex[1].z == 0.0 and
                         triangleset_triangulated.triangles[0].vertex[2].x == -10.0 and
                         triangleset_triangulated.triangles[0].vertex[2].y == -10.0 and
                         triangleset_triangulated.triangles[0].vertex[2].z == 0.0)
            self.assert_(triangleset_triangulated.triangles[1].vertex[0].x == 10.0 and
                         triangleset_triangulated.triangles[1].vertex[0].y == 10.0 and
                         triangleset_triangulated.triangles[1].vertex[0].z == 0.0 and
                         triangleset_triangulated.triangles[1].vertex[1].x == -10.0 and
                         triangleset_triangulated.triangles[1].vertex[1].y == 10.0 and
                         triangleset_triangulated.triangles[1].vertex[1].z == 0.0 and
                         triangleset_triangulated.triangles[1].vertex[2].x == -10.0 and
                         triangleset_triangulated.triangles[1].vertex[2].y == -10.0 and
                         triangleset_triangulated.triangles[1].vertex[2].z == 0.0)

        def test_barrel_triangulation_no_transformation(self):
            barrel_triangulated = TriangulatedPolygon(object=self.barrel, name=self.barrel_objectdef.get_name())
            self.assert_(len(barrel_triangulated.triangles) == 80)

        def test_cuboid_triangulation_no_transformations(self):
            cuboid_triangulated = TriangulatedPolygon(object=self.cuboid, name=self.cuboid_objectdef.get_name())
            self.assert_(len(cuboid_triangulated.triangles) == 12)
            self.assert_(cuboid_triangulated.triangles[0].vertex[0].x == -0.5 and
                         cuboid_triangulated.triangles[0].vertex[0].y == -0.5 and
                         cuboid_triangulated.triangles[0].vertex[0].z == -0.5 and
                         cuboid_triangulated.triangles[0].vertex[1].x == -0.5 and
                         cuboid_triangulated.triangles[0].vertex[1].y == -0.5 and
                         cuboid_triangulated.triangles[0].vertex[1].z == +0.5 and
                         cuboid_triangulated.triangles[0].vertex[2].x == -0.5 and
                         cuboid_triangulated.triangles[0].vertex[2].y == +0.5 and
                         cuboid_triangulated.triangles[0].vertex[2].z == +0.5)
            self.assert_(cuboid_triangulated.triangles[1].vertex[0].x == -0.5 and
                         cuboid_triangulated.triangles[1].vertex[0].y == -0.5 and
                         cuboid_triangulated.triangles[1].vertex[0].z == -0.5 and
                         cuboid_triangulated.triangles[1].vertex[1].x == -0.5 and
                         cuboid_triangulated.triangles[1].vertex[1].y == +0.5 and
                         cuboid_triangulated.triangles[1].vertex[1].z == +0.5 and
                         cuboid_triangulated.triangles[1].vertex[2].x == -0.5 and
                         cuboid_triangulated.triangles[1].vertex[2].y == +0.5 and
                         cuboid_triangulated.triangles[1].vertex[2].z == -0.5)
            self.assert_(cuboid_triangulated.triangles[2].vertex[0].x == +0.5 and
                         cuboid_triangulated.triangles[2].vertex[0].y == -0.5 and
                         cuboid_triangulated.triangles[2].vertex[0].z == -0.5 and
                         cuboid_triangulated.triangles[2].vertex[1].x == +0.5 and
                         cuboid_triangulated.triangles[2].vertex[1].y == +0.5 and
                         cuboid_triangulated.triangles[2].vertex[1].z == -0.5 and
                         cuboid_triangulated.triangles[2].vertex[2].x == +0.5 and
                         cuboid_triangulated.triangles[2].vertex[2].y == +0.5 and
                         cuboid_triangulated.triangles[2].vertex[2].z == +0.5)
            self.assert_(cuboid_triangulated.triangles[3].vertex[0].x == +0.5 and
                         cuboid_triangulated.triangles[3].vertex[0].y == -0.5 and
                         cuboid_triangulated.triangles[3].vertex[0].z == -0.5 and
                         cuboid_triangulated.triangles[3].vertex[1].x == +0.5 and
                         cuboid_triangulated.triangles[3].vertex[1].y == +0.5 and
                         cuboid_triangulated.triangles[3].vertex[1].z == +0.5 and
                         cuboid_triangulated.triangles[3].vertex[2].x == +0.5 and
                         cuboid_triangulated.triangles[3].vertex[2].y == -0.5 and
                         cuboid_triangulated.triangles[3].vertex[2].z == +0.5)
            self.assert_(cuboid_triangulated.triangles[4].vertex[0].x == -0.5 and
                         cuboid_triangulated.triangles[4].vertex[0].y == -0.5 and
                         cuboid_triangulated.triangles[4].vertex[0].z == -0.5 and
                         cuboid_triangulated.triangles[4].vertex[1].x == +0.5 and
                         cuboid_triangulated.triangles[4].vertex[1].y == -0.5 and
                         cuboid_triangulated.triangles[4].vertex[1].z == -0.5 and
                         cuboid_triangulated.triangles[4].vertex[2].x == +0.5 and
                         cuboid_triangulated.triangles[4].vertex[2].y == -0.5 and
                         cuboid_triangulated.triangles[4].vertex[2].z == +0.5)
            self.assert_(cuboid_triangulated.triangles[5].vertex[0].x == -0.5 and
                         cuboid_triangulated.triangles[5].vertex[0].y == -0.5 and
                         cuboid_triangulated.triangles[5].vertex[0].z == -0.5 and
                         cuboid_triangulated.triangles[5].vertex[1].x == +0.5 and
                         cuboid_triangulated.triangles[5].vertex[1].y == -0.5 and
                         cuboid_triangulated.triangles[5].vertex[1].z == +0.5 and
                         cuboid_triangulated.triangles[5].vertex[2].x == -0.5 and
                         cuboid_triangulated.triangles[5].vertex[2].y == -0.5 and
                         cuboid_triangulated.triangles[5].vertex[2].z == +0.5)
            self.assert_(cuboid_triangulated.triangles[6].vertex[0].x == -0.5 and
                         cuboid_triangulated.triangles[6].vertex[0].y == +0.5 and
                         cuboid_triangulated.triangles[6].vertex[0].z == -0.5 and
                         cuboid_triangulated.triangles[6].vertex[1].x == -0.5 and
                         cuboid_triangulated.triangles[6].vertex[1].y == +0.5 and
                         cuboid_triangulated.triangles[6].vertex[1].z == +0.5 and
                         cuboid_triangulated.triangles[6].vertex[2].x == +0.5 and
                         cuboid_triangulated.triangles[6].vertex[2].y == +0.5 and
                         cuboid_triangulated.triangles[6].vertex[2].z == +0.5)
            self.assert_(cuboid_triangulated.triangles[7].vertex[0].x == -0.5 and
                         cuboid_triangulated.triangles[7].vertex[0].y == +0.5 and
                         cuboid_triangulated.triangles[7].vertex[0].z == -0.5 and
                         cuboid_triangulated.triangles[7].vertex[1].x == +0.5 and
                         cuboid_triangulated.triangles[7].vertex[1].y == +0.5 and
                         cuboid_triangulated.triangles[7].vertex[1].z == +0.5 and
                         cuboid_triangulated.triangles[7].vertex[2].x == +0.5 and
                         cuboid_triangulated.triangles[7].vertex[2].y == +0.5 and
                         cuboid_triangulated.triangles[7].vertex[2].z == -0.5)
            self.assert_(cuboid_triangulated.triangles[8].vertex[0].x == -0.5 and
                         cuboid_triangulated.triangles[8].vertex[0].y == -0.5 and
                         cuboid_triangulated.triangles[8].vertex[0].z == -0.5 and
                         cuboid_triangulated.triangles[8].vertex[1].x == -0.5 and
                         cuboid_triangulated.triangles[8].vertex[1].y == +0.5 and
                         cuboid_triangulated.triangles[8].vertex[1].z == -0.5 and
                         cuboid_triangulated.triangles[8].vertex[2].x == +0.5 and
                         cuboid_triangulated.triangles[8].vertex[2].y == +0.5 and
                         cuboid_triangulated.triangles[8].vertex[2].z == -0.5)
            self.assert_(cuboid_triangulated.triangles[9].vertex[0].x == -0.5 and
                         cuboid_triangulated.triangles[9].vertex[0].y == -0.5 and
                         cuboid_triangulated.triangles[9].vertex[0].z == -0.5 and
                         cuboid_triangulated.triangles[9].vertex[1].x == +0.5 and
                         cuboid_triangulated.triangles[9].vertex[1].y == +0.5 and
                         cuboid_triangulated.triangles[9].vertex[1].z == -0.5 and
                         cuboid_triangulated.triangles[9].vertex[2].x == +0.5 and
                         cuboid_triangulated.triangles[9].vertex[2].y == -0.5 and
                         cuboid_triangulated.triangles[9].vertex[2].z == -0.5)
            self.assert_(cuboid_triangulated.triangles[10].vertex[0].x == -0.5 and
                         cuboid_triangulated.triangles[10].vertex[0].y == -0.5 and
                         cuboid_triangulated.triangles[10].vertex[0].z == +0.5 and
                         cuboid_triangulated.triangles[10].vertex[1].x == +0.5 and
                         cuboid_triangulated.triangles[10].vertex[1].y == -0.5 and
                         cuboid_triangulated.triangles[10].vertex[1].z == +0.5 and
                         cuboid_triangulated.triangles[10].vertex[2].x == +0.5 and
                         cuboid_triangulated.triangles[10].vertex[2].y == +0.5 and
                         cuboid_triangulated.triangles[10].vertex[2].z == +0.5)
            self.assert_(cuboid_triangulated.triangles[11].vertex[0].x == -0.5 and
                         cuboid_triangulated.triangles[11].vertex[0].y == -0.5 and
                         cuboid_triangulated.triangles[11].vertex[0].z == +0.5 and
                         cuboid_triangulated.triangles[11].vertex[1].x == +0.5 and
                         cuboid_triangulated.triangles[11].vertex[1].y == +0.5 and
                         cuboid_triangulated.triangles[11].vertex[1].z == +0.5 and
                         cuboid_triangulated.triangles[11].vertex[2].x == -0.5 and
                         cuboid_triangulated.triangles[11].vertex[2].y == +0.5 and
                         cuboid_triangulated.triangles[11].vertex[2].z == +0.5)

        def test_cuboid_triangulation_transformed(self):
            for pairs in self.transformations:
                if objectdefForObject(self.inscene, pairs[0]) == self.cuboid_objectdef:
                    cuboid_triangulated = TriangulatedPolygon(object=self.cuboid, transformation_matrix=pairs[1], name=self.cuboid_objectdef.get_name())
                    self.assert_(len(cuboid_triangulated.triangles) == 12)
                    self.assert_(cuboid_triangulated.triangles[0].vertex[0].x == -3.0 and
                                 cuboid_triangulated.triangles[0].vertex[0].y == -2.0 and
                                 cuboid_triangulated.triangles[0].vertex[0].z == -2.0 and
                                 cuboid_triangulated.triangles[0].vertex[1].x == -3.0 and
                                 cuboid_triangulated.triangles[0].vertex[1].y == -2.0 and
                                 cuboid_triangulated.triangles[0].vertex[1].z == +2.0 and
                                 cuboid_triangulated.triangles[0].vertex[2].x == -3.0 and
                                 cuboid_triangulated.triangles[0].vertex[2].y == 0.0 and
                                 cuboid_triangulated.triangles[0].vertex[2].z == +2.0)
                    self.assert_(cuboid_triangulated.triangles[1].vertex[0].x == -3.0 and
                                 cuboid_triangulated.triangles[1].vertex[0].y == -2.0 and
                                 cuboid_triangulated.triangles[1].vertex[0].z == -2.0 and
                                 cuboid_triangulated.triangles[1].vertex[1].x == -3.0 and
                                 cuboid_triangulated.triangles[1].vertex[1].y == 0.0 and
                                 cuboid_triangulated.triangles[1].vertex[1].z == +2.0 and
                                 cuboid_triangulated.triangles[1].vertex[2].x == -3.0 and
                                 cuboid_triangulated.triangles[1].vertex[2].y == 0.0 and
                                 cuboid_triangulated.triangles[1].vertex[2].z == -2.0)
                    self.assert_(cuboid_triangulated.triangles[2].vertex[0].x == +3.0 and
                                 cuboid_triangulated.triangles[2].vertex[0].y == -2.0 and
                                 cuboid_triangulated.triangles[2].vertex[0].z == -2.0 and
                                 cuboid_triangulated.triangles[2].vertex[1].x == +3.0 and
                                 cuboid_triangulated.triangles[2].vertex[1].y == 0.0 and
                                 cuboid_triangulated.triangles[2].vertex[1].z == -2.0 and
                                 cuboid_triangulated.triangles[2].vertex[2].x == +3.0 and
                                 cuboid_triangulated.triangles[2].vertex[2].y == 0.0 and
                                 cuboid_triangulated.triangles[2].vertex[2].z == +2.0)
                    self.assert_(cuboid_triangulated.triangles[3].vertex[0].x == +3.0 and
                                 cuboid_triangulated.triangles[3].vertex[0].y == -2.0 and
                                 cuboid_triangulated.triangles[3].vertex[0].z == -2.0 and
                                 cuboid_triangulated.triangles[3].vertex[1].x == +3.0 and
                                 cuboid_triangulated.triangles[3].vertex[1].y == 0.0 and
                                 cuboid_triangulated.triangles[3].vertex[1].z == +2.0 and
                                 cuboid_triangulated.triangles[3].vertex[2].x == +3.0 and
                                 cuboid_triangulated.triangles[3].vertex[2].y == -2.0 and
                                 cuboid_triangulated.triangles[3].vertex[2].z == +2.0)
                    self.assert_(cuboid_triangulated.triangles[4].vertex[0].x == -3.0 and
                                 cuboid_triangulated.triangles[4].vertex[0].y == -2.0 and
                                 cuboid_triangulated.triangles[4].vertex[0].z == -2.0 and
                                 cuboid_triangulated.triangles[4].vertex[1].x == +3.0 and
                                 cuboid_triangulated.triangles[4].vertex[1].y == -2.0 and
                                 cuboid_triangulated.triangles[4].vertex[1].z == -2.0 and
                                 cuboid_triangulated.triangles[4].vertex[2].x == +3.0 and
                                 cuboid_triangulated.triangles[4].vertex[2].y == -2.0 and
                                 cuboid_triangulated.triangles[4].vertex[2].z == +2.0)
                    self.assert_(cuboid_triangulated.triangles[5].vertex[0].x == -3.0 and
                                 cuboid_triangulated.triangles[5].vertex[0].y == -2.0 and
                                 cuboid_triangulated.triangles[5].vertex[0].z == -2.0 and
                                 cuboid_triangulated.triangles[5].vertex[1].x == +3.0 and
                                 cuboid_triangulated.triangles[5].vertex[1].y == -2.0 and
                                 cuboid_triangulated.triangles[5].vertex[1].z == +2.0 and
                                 cuboid_triangulated.triangles[5].vertex[2].x == -3.0 and
                                 cuboid_triangulated.triangles[5].vertex[2].y == -2.0 and
                                 cuboid_triangulated.triangles[5].vertex[2].z == +2.0)
                    self.assert_(cuboid_triangulated.triangles[6].vertex[0].x == -3.0 and
                                 cuboid_triangulated.triangles[6].vertex[0].y == 0.0 and
                                 cuboid_triangulated.triangles[6].vertex[0].z == -2.0 and
                                 cuboid_triangulated.triangles[6].vertex[1].x == -3.0 and
                                 cuboid_triangulated.triangles[6].vertex[1].y == 0.0 and
                                 cuboid_triangulated.triangles[6].vertex[1].z == +2.0 and
                                 cuboid_triangulated.triangles[6].vertex[2].x == +3.0 and
                                 cuboid_triangulated.triangles[6].vertex[2].y == 0.0 and
                                 cuboid_triangulated.triangles[6].vertex[2].z == +2.0)
                    self.assert_(cuboid_triangulated.triangles[7].vertex[0].x == -3.0 and
                                 cuboid_triangulated.triangles[7].vertex[0].y == 0.0 and
                                 cuboid_triangulated.triangles[7].vertex[0].z == -2.0 and
                                 cuboid_triangulated.triangles[7].vertex[1].x == +3.0 and
                                 cuboid_triangulated.triangles[7].vertex[1].y == 0.0 and
                                 cuboid_triangulated.triangles[7].vertex[1].z == +2.0 and
                                 cuboid_triangulated.triangles[7].vertex[2].x == +3.0 and
                                 cuboid_triangulated.triangles[7].vertex[2].y == 0.0 and
                                 cuboid_triangulated.triangles[7].vertex[2].z == -2.0)
                    self.assert_(cuboid_triangulated.triangles[8].vertex[0].x == -3.0 and
                                 cuboid_triangulated.triangles[8].vertex[0].y == -2.0 and
                                 cuboid_triangulated.triangles[8].vertex[0].z == -2.0 and
                                 cuboid_triangulated.triangles[8].vertex[1].x == -3.0 and
                                 cuboid_triangulated.triangles[8].vertex[1].y == 0.0 and
                                 cuboid_triangulated.triangles[8].vertex[1].z == -2.0 and
                                 cuboid_triangulated.triangles[8].vertex[2].x == +3.0 and
                                 cuboid_triangulated.triangles[8].vertex[2].y == 0.0 and
                                 cuboid_triangulated.triangles[8].vertex[2].z == -2.0)
                    self.assert_(cuboid_triangulated.triangles[9].vertex[0].x == -3.0 and
                                 cuboid_triangulated.triangles[9].vertex[0].y == -2.0 and
                                 cuboid_triangulated.triangles[9].vertex[0].z == -2.0 and
                                 cuboid_triangulated.triangles[9].vertex[1].x == +3.0 and
                                 cuboid_triangulated.triangles[9].vertex[1].y == 0.0 and
                                 cuboid_triangulated.triangles[9].vertex[1].z == -2.0 and
                                 cuboid_triangulated.triangles[9].vertex[2].x == +3.0 and
                                 cuboid_triangulated.triangles[9].vertex[2].y == -2.0 and
                                 cuboid_triangulated.triangles[9].vertex[2].z == -2.0)
                    self.assert_(cuboid_triangulated.triangles[10].vertex[0].x == -3.0 and
                                 cuboid_triangulated.triangles[10].vertex[0].y == -2.0 and
                                 cuboid_triangulated.triangles[10].vertex[0].z == +2.0 and
                                 cuboid_triangulated.triangles[10].vertex[1].x == +3.0 and
                                 cuboid_triangulated.triangles[10].vertex[1].y == -2.0 and
                                 cuboid_triangulated.triangles[10].vertex[1].z == +2.0 and
                                 cuboid_triangulated.triangles[10].vertex[2].x == +3.0 and
                                 cuboid_triangulated.triangles[10].vertex[2].y == 0.0 and
                                 cuboid_triangulated.triangles[10].vertex[2].z == +2.0)
                    self.assert_(cuboid_triangulated.triangles[11].vertex[0].x == -3.0 and
                                 cuboid_triangulated.triangles[11].vertex[0].y == -2.0 and
                                 cuboid_triangulated.triangles[11].vertex[0].z == +2.0 and
                                 cuboid_triangulated.triangles[11].vertex[1].x == +3.0 and
                                 cuboid_triangulated.triangles[11].vertex[1].y == 0.0 and
                                 cuboid_triangulated.triangles[11].vertex[1].z == +2.0 and
                                 cuboid_triangulated.triangles[11].vertex[2].x == -3.0 and
                                 cuboid_triangulated.triangles[11].vertex[2].y == 0.0 and
                                 cuboid_triangulated.triangles[11].vertex[2].z == +2.0)
                    return # only one cuboid in infile

    unittest.main()
